package com.kzw.core.mapper;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;


@SuppressWarnings("unchecked")
public class ObjectUtil {

	public static class test {
		String name;
		String age;
		test t;
	}

	/**
	 * 将object中的某些属性置为null
	 * 用作属性过滤的时候，请尽量自行过滤无关属性，比如：用 page.setResult(ObjectUtil.setNull(page.getResult(),2)) 而不是ObjectUtil.setNull(page,3) 
	 * <br/>
	 * 其中num指定了遍历程度，如果只需要本对象下的所有属性（二级对象忽略），可以这样写ObjectUtil.setNull(obj,1)依次类推
	 * @param <T>
	 * @param object
	 * @param num 对象本身算一级
	 * @param propertys
	 * @return
	 */
	public static <T> T setNull(T object, Integer num, String... propertys) {
		if (object == null) {
			return null;
		}
		if (num == 0) {
			return object;
		}
		num--;
		Class c = object.getClass();
		String className=c.getName();
		if(className.matches(".*_\\$\\$_javassist_[0-9]+")){
			className=className.replaceAll("_\\$\\$_javassist_[0-9]+", "");//.replace("_$$_javassist_[0-9]+","");
			c=getClassFormName(className);
		}
		if (Number.class.isAssignableFrom(c)
				|| Boolean.class.isAssignableFrom(c)
				|| String.class.isAssignableFrom(c)
				|| Date.class.isAssignableFrom(c)
				|| java.sql.Date.class.isAssignableFrom(c)) {
			return object;
		}
		if (c.isArray()) {
			Object[] objs = (Object[]) object;
			for (int i = 0; i < objs.length; i++) {
				objs[i] = setNull(objs[i], num+1, propertys);
			}
			return (T) objs;
		}
		if (Collection.class.isAssignableFrom(c)) {// 如果该属性为集合属性
			try {
				Collection<Object> temp = (Collection<Object>) c.newInstance();
				Collection<Object> col = (Collection<Object>) object;
				for (Object o : col) {
					temp.add(setNull(o, num+1, propertys));
				}
				return (T) temp;
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		List<String> prolist = new java.util.ArrayList<String>();
		for (String s : propertys) {
			prolist.add(s);
		}
		try {
			Object objs = c.newInstance();
			for (Method m : c.getMethods()) {
				String name = m.getName();
				if (name.startsWith("set")) {
					String filedName = StringUtils.uncapitalize(name.replace(
							"set", ""));
					if (!prolist.contains(filedName)
							&& m.getParameterTypes().length == 1
							&& !name.equals("setHandler")) {
						try {
							//String s="get" + StringUtils.capitalize(filedName);
							Object r = c.getMethod(
									"get" + StringUtils.capitalize(filedName))
									.invoke(object);
							r=setNull(r, num, propertys);
							m.invoke(objs, r);
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (InvocationTargetException e) {
							//e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}
					}
				}
			}
			return (T) objs;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 将obj中属性名不在propertys内的属性置空
	 * 
	 * @param <T>
	 * @param obj
	 * @param num 对象本身算一级
	 * @param propertys
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T filter(T obj, int num, String... propertys) {
		if (obj == null) {
			return null;
		}
		if (num == 0) {
			return obj;
		}
		num--;
		Class c = obj.getClass();
		String className=c.getName();
		if(className.matches(".*_\\$\\$_javassist_[0-9]+")){
			className=className.replaceAll("_\\$\\$_javassist_[0-9]+", "");//
			c=getClassFormName(className);
		}
		//Class.forName(className)
		if (Number.class.isAssignableFrom(c)
				|| String.class.isAssignableFrom(c)
				|| Date.class.isAssignableFrom(c)
				|| java.sql.Date.class.isAssignableFrom(c)) {
			return obj;
		}
		if (c.isArray()) {
			Object[] objs = (Object[]) obj;
			for (int i = 0; i < objs.length; i++) {
				objs[i] = filter(objs[i], num, propertys);
			}
			return (T) objs;
		}
		if (Collection.class.isAssignableFrom(c)) {// 如果该属性为集合属性
			try {
				Collection<Object> t = (Collection<Object>) c.newInstance();
				Collection<Object> col = (Collection<Object>) obj;
				for (Object o : col) {
					t.add(filter(o, num, propertys));
				}
				return (T) t;
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		List<String> prolist = new java.util.ArrayList<String>();
		for (String s : propertys) {
			prolist.add(s);
		}
		try {
			Object objs = c.newInstance();
			for (Method m : c.getMethods()) {
				String name = m.getName();
				if (name.startsWith("set")) {
					String filedName = StringUtils.uncapitalize(name.replace(
							"set", ""));
					if (prolist.contains(filedName)
							&& m.getParameterTypes().length == 1
							&& !name.equals("setHandler")) {
						try {
							Object r = c.getMethod(
									"get" + StringUtils.capitalize(filedName))
									.invoke(obj);
							m.invoke(objs, filter(r, num, propertys));
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						} catch (InvocationTargetException e) {
							e.printStackTrace();
						} catch (IllegalAccessException e) {
							e.printStackTrace();
						}
					}
				}
			}
			return (T) objs;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	private static Map<String, Class> classTemp = new HashMap<String, Class>();
	private static Class getClassFormName(String name){
		if(!classTemp.containsKey(name)){
			try {
				classTemp.put(name, Class.forName(name));
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		return classTemp.get(name);
	}
}
